################################################################################
#
#Copyright (c) 2011, Petr Skramovsky
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions are met:
#    * Redistributions of source code must retain the above copyright
#      notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above copyright
#      notice, this list of conditions and the following disclaimer in the
#      documentation and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#DISCLAIMED. IN NO EVENT SHALL Petr Skramovsky BE LIABLE FOR ANY
#DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
################################################################################

SHADER_SURFACEPARAM = "surfaceparam"
SHADER_MAP = "map"
SHADER_TCMOD = "tcmod"
SHADER_BLEDFUNC = "blendfunc"
SHADER_PORTAL = "portal"
SHADER_POLYGONOFFSET = "polygonoffset"
SHADER_NOMIPMAP = "nomipmap"
SHADER_NOPICMIP = "nopicmip"

#surface params
SHADER_ALPHASHADOW = "alphashadow"
SHADER_AREAPORTAL = "areaportal"
SHADER_CLUSTERPORTAL = "clusterportal"
SHADER_DONOTENTER = "donotenter"
SHADER_FLESH = "flesh"
SHADER_FOG = "fog"
SHADER_LAVA = "lava"
SHADER_METALSTEPS = "metalsteps"
SHADER_NODAMAGE = "nodamage"
SHADER_NODLIGHT = "nodlight"
SHADER_NODRAW = "nodraw"
SHADER_NODROP = "nodrop"
SHADER_NOIMPACT = "noimpact"
SHADER_NOMARKS = "nomarks"
SHADER_NOLIGHTMAP = "nolightmap"
SHADER_NOSTEPS = "nosteps"
SHADER_NONSOLID = "nonsolid"
SHADER_ORIGIN = "origin"
SHADER_PLAYERCLIP = "playerclip"
SHADER_SLICK = "slick"
SHADER_SLIME = "slime"
SHADER_STRUCTURAL = "structural"
SHADER_TRANS = "trans"
SHADER_WATER = "water"

#waveform funcs
SHADER_SIN = "sin"
SHADER_TRIANGLE = "triangle"
SHADER_SQUARE = "square"
SHADER_SAWTOOTH = "sawtooth"
SHADER_INVERSESAWTOOTH = "inversesawtooth"

#cull sides
SHADER_FRONT = "front"
SHADER_BACK = "back"
SHADER_DISABLE = "disable"
SHADER_NONE = "none"

#sort values
SHADER_PORTAL = "portal"
SHADER_SKY = "sky"
SHADER_OPAQUE = "opaque"
SHADER_BANNER = "banner"
SHADER_UNDERWATER = "underwater"
SHADER_ADDITIVE = "additive"
SHADER_NEAREST = "nearest"

SHADER_LIGHTMAP = "$lightmap"


class Shader:
  def __init__(self,name,params=[],layers=[]):
    self.name = name
    self.params = params
    self.layers = layers

class ShaderLayer:
  def __init__(self,params=[]):
    self.params = params

class ShaderParam:
  def __init__(self,name,values):
    self.name = name
    self.values = values

class ShaderReader:

  STATE_START = 0
  STATE_NAME = 1
  STATE_PARAMS = 2
  STATE_LAYER_PARAMS = 3
  STATE_SHADER_START = 4

  def is_ignored(self,line):
    return line == "" or line.startswith( "//" )

  def parse_param(self,line):
    sp = line.split(" ")
    return ShaderParam(sp[0],sp[1:])

  def read(self,file):
    shaders = []
    state = self.STATE_START
    for line in file:
      line = line.rstrip().lstrip().lower()
      if self.is_ignored(line):
        continue
      if state == self.STATE_START :
        shaders.append( Shader( line ) )
        #print "+shader:" + line
        state = self.STATE_SHADER_START
        continue
      if state == self.STATE_SHADER_START :
        assert line == "{"
        state = self.STATE_PARAMS
        continue
      if state == self.STATE_PARAMS :
        shader = shaders[ -1 ]
        if line == "}":
          state = self.STATE_START
          continue
        #TODO:fix this { blablabla
        if line.startswith( "{" ):
          shader.layers.append(ShaderLayer())
          #print "--+layer"
          state = self.STATE_LAYER_PARAMS
          continue
        #print "--param:" + line
        shader.params.append( self.parse_param( line ) )
        continue
      if state == self.STATE_LAYER_PARAMS :
        assert line != "{"
        if line == "}":
          state = self.STATE_PARAMS
          continue
        #print "----param:" + line
        layer = shaders[ -1 ].layers[ -1 ]
        layer.params.append( self.parse_param( line ) )
        continue

    rshds = {}
    for s in shaders:
      rshds[ s.name ] = s
      
    return rshds

def texture_to_shader(tex):
  sp = tex.split("/")
  if len( sp ) == 1:
    return None
  return "scripts/" + sp[ 1 ] + ".shader"

      